#include <parg.h>
#include <signal.h>
#include "yaml/parse_cfg.h"
#include "modbus/mb_tcp_slave.h"
#include "mqtt/mqtt.h"
#include "matiec/st.h"

static sys_ctrl_t _ctrl;

void stop_check(uv_timer_t *handle)
{
	// run stop check
	char *data = "hello this /dev/rhb01";
	mqtt_client_publish(&_ctrl, data, strlen(data));
	// xx_log_info("stop check");

}

static void close_sigint(int dummy)
{
	xx_log_info("ctrl + c to exit");
	xx_deinit_logger();
	mb_slave_deinit();
	exit(dummy);
}

int cmdline_parse(int argc, char **argv, char *file)
{
	if (argc == 1)
	{
		printf("Usage: %s [-h] [-v] [-c yaml_cfg_file]\n", argv[0]);
		exit(1);
	}
	struct parg_state ps;
	int c;
	parg_init(&ps);
	while ((c = parg_getopt(&ps, argc, argv, "hc:v")) != -1)
	{
		switch (c)
		{
		case 'h':
			printf("Usage: %s [-h] [-v] [-c yaml_cfg_file]\n", argv[0]);
			exit(2);
		case 'c':
			memcpy(file, ps.optarg, strlen(ps.optarg));
			printf("load cfg file: \"%s\"\n", ps.optarg);
			break;
		case 'v':
			printf("version: %s\n", (char *)GITLAB_FETCH_ID);
			exit(3);
		default:
			printf("Usage: %s [-h] [-v] [-c yaml_cfg_file]\n", argv[0]);
			exit(4);
		}
	}
	return 0;
}

void uv_async_mqtt_cb(uv_async_t *handle)
{
	// 解析mqtt参数赋值给_ctrl使用
	char * buf = uv_handle_get_data((uv_handle_t*)handle);
	xx_log_info("mqtt sub topic :%s", buf);
	free(buf);
}

int main(int argc, char **argv)
{
	signal(SIGINT, close_sigint);

	// parse cmdline
	char cfg_file[64] = {0};
	cmdline_parse(argc, argv, cfg_file);

	// parse yaml cfg file
	yaml_parse(cfg_file, &_ctrl.cfg);

	// init logger
	xx_init_logger(_ctrl.cfg.log.log_dir, _ctrl.cfg.log.max_files);
	xx_log_info("init logger");

	mb_slave_init(&_ctrl.cfg);

	// init libuv
	_ctrl.loop = uv_default_loop();
	uv_async_init(_ctrl.loop, &_ctrl.async_mqtt, uv_async_mqtt_cb);
	mqtt_client_init(&_ctrl);

	uv_timer_t gc_req;
	uv_timer_init(_ctrl.loop, &gc_req);
	uv_timer_start(&gc_req, stop_check, 1000, 3000);

	uv_run(_ctrl.loop, UV_RUN_DEFAULT);
	uv_loop_close(_ctrl.loop);
	mb_slave_deinit();
	mqtt_client_destory(&_ctrl);
	xx_deinit_logger();
	return 0;
}
